﻿namespace Triad.Controls
{
    #region Usings

    using System;
    using System.Collections;
    using System.Data;
    using System.Text;
    using System.Web.UI.WebControls;
    using System.Web.UI;
    #endregion

    /// <summary>
    /// 
    /// </summary>
    public partial class tfListView
    {
        /// <summary>
        /// Registers the script.
        /// </summary>
        /// <returns>All Javascript rendered to client to build table via DOM manipulation</returns>
        /// <remarks>
        /// Author: tim.fischer,   7/2/2008 - 9:05 AM
        /// Modified By: 
        /// </remarks>
        private string RegisterScript()
        {
            var jshtml = new StringBuilder();

            //if (c_MyTable != null)
            //{
                jshtml.AppendFormat("{0} = new tfListView(\"{0}\",\"{0}RDiv\",\"{0}RDiv\", {1});{2}",
                                    ClientID, RenderOnClient.ToString().ToLower(), c_NewLine);

                //jshtml.Append(ClientID + ".ResourcePath = '" + ResourcePath.Replace("\\", "\\\\") + "';");
                if (ReadOnly)
                {
                    jshtml.Append(ClientID + ".ReadOnly = true;");
                    jshtml.Append(ClientID + ".AllowEditTemplate = false;");
                    jshtml.Append(ClientID + ".AllowEdit = false;");
                    jshtml.Append(ClientID + ".AllowDelete = false;");
                    jshtml.Append(ClientID + ".AllowAdd = false;");
                }
                else
                {
                    jshtml.Append(ClientID + ".AllowEditTemplate = " + AllowEditTemplate.ToString().ToLower() + ";");
                    jshtml.Append(ClientID + ".AllowEdit = " + AllowEdit.ToString().ToLower() + ";");
                    jshtml.Append(ClientID + ".AllowDelete = " + AllowDelete.ToString().ToLower() + ";");
                    jshtml.Append(ClientID + ".AllowAdd = " + AllowAdd.ToString().ToLower() + ";");
                }

                jshtml.AppendFormat("{0}.SendAllRowsInCallback={1};", ClientID, SendAllRowsInCallback.ToString().ToLower());
                jshtml.AppendFormat("{0}.AllowUserSelection={1};", ClientID, AllowUserSelection.ToString().ToLower());
                jshtml.AppendFormat("{0}.EnableExport={1};", ClientID, EnableExport.ToString().ToLower());
                jshtml.AppendFormat("{0}.AllowMultiSelect={1};{2}", ClientID, AllowMultiSelect.ToString().ToLower(), c_NewLine);
                jshtml.AppendFormat("{0}.AllowSearch={1};{2}", ClientID, AllowSearch.ToString().ToLower(), c_NewLine);
                jshtml.AppendFormat("{0}.AllowMoveRows={1};{2}", ClientID, AllowMoveRows.ToString().ToLower(), c_NewLine);
                jshtml.AppendFormat("{0}.AllowGroupBy={1};{2}", ClientID, AllowGroupBy.ToString().ToLower(), c_NewLine);
                jshtml.AppendFormat("{0}.AllowResize={1};{2}", ClientID, AllowResize.ToString().ToLower(), c_NewLine);
                jshtml.AppendFormat("{0}.AllowPaging={1};{2}", ClientID, AllowPaging.ToString().ToLower(), c_NewLine);
                jshtml.AppendFormat("{0}.AllowSorting={1};{2}", ClientID, AllowSorting.ToString().ToLower(), c_NewLine);
                jshtml.AppendFormat("{0}.Height = '{1}';", ClientID, GridHeight);
                jshtml.AppendFormat("{0}.Width = '{1}';", ClientID, GridWidth);
                jshtml.AppendFormat("{0}.TemplateTitle = '{1}';", ClientID, _templateTitle);
                jshtml.AppendFormat("{0}.FreezeHeader = '{1}';", ClientID, FreezeHeader.ToString().ToLower());
                //jshtml.AppendFormat("{0}.FreezeColumnOne = '{1}';", ClientID, FreezeColumnOne.ToString().ToLower());
                //jshtml.AppendFormat("{0}.AlternatingRowClass='{1}';{2}", ClientID, CSSTheme.AlternatingRowClass, c_NewLine);
                //jshtml.AppendFormat("{0}.EditRowClass='{1}';{2}", ClientID, CSSTheme.EditRowClass, c_NewLine);
                //jshtml.AppendFormat("{0}.FooterClass='{1}';{2}", ClientID, CSSTheme.FooterClass, c_NewLine);
                //jshtml.AppendFormat("{0}.HeaderClass='{1}';{2}", ClientID, CSSTheme.HeaderClass, c_NewLine);
                //jshtml.AppendFormat("{0}.RowClass='{1}';{2}", ClientID, CSSTheme.RowClass, c_NewLine);
                //jshtml.AppendFormat("{0}.SelectedRowClass='{1}';{2}", ClientID, CSSTheme.SelectedRowClass, c_NewLine);
                //jshtml.AppendFormat("{0}.GroupByItemClass='{1}';{2}", ClientID, CSSTheme.GroupByItemClass, c_NewLine);
                //jshtml.AppendFormat("{0}.GroupByTableClass='{1}';{2}", ClientID, CSSTheme.GroupByTableClass, c_NewLine);
                //jshtml.AppendFormat("{0}.GroupByTableItemClass='{1}';{2}", ClientID, CSSTheme.GroupByTableItemClass, c_NewLine);
                //jshtml.AppendFormat("{0}.SelectorItemSingleClass='{1}';{2}", ClientID, CSSTheme.SelectorItemSingleClass, c_NewLine);
                //jshtml.AppendFormat("{0}.SelectorItemMultiClass='{1}';{2}", ClientID, CSSTheme.SelectorItemMultiClass, c_NewLine);
                //jshtml.AppendFormat("{0}.SearchClass='{1}';{2}", ClientID, CSSTheme.SearchClass, c_NewLine);
                if (AllowPaging)
                {
                    jshtml.AppendFormat("{0}.RowLimit={1};{2}", ClientID, PageSize, c_NewLine);
                }
                if (c_ClearAllSelectedRows)
                {
                    jshtml.Replace("new Array(\"1", "new Array(\"0");
                    if (c_MyTable != null)
                    {
                        DataRow[] rowList = c_MyTable.Select("_tfAT = '10'");
                        foreach (DataRow dr in rowList)
                        {
                            dr["_tfAT"] = "00";
                        }
                    }

                }

                if (c_MyTable != null)
                {
                    int i = 0;
                    foreach (DataRow row in c_MyTable.Rows)
                    {
                        jshtml.Append(GetRowJS(c_MyTable, row,i));
                        i++;
                    }
                }

                for (int nX = 0; nX < Columns.Count; nX++)
                {
                    DataControlField column = Columns[nX];
                    jshtml.Append(GetColumnJS(column, "SmlTblTitle3",nX==(Columns.Count-1)));
                }

                //jshtml.AppendFormat("{0}.DataSetName = '{1}';", ClientID, ClientID + "DS");
                jshtml.AppendFormat("{0}.TableName = '{1}';{2}", ClientID, ClientID + "T", c_NewLine);
                if (c_MyTable != null)
                {
                    jshtml.AppendFormat("{0}.DataSetNamespace = '{1}';{2}", ClientID, c_MyTable.Namespace, c_NewLine);
                }
                jshtml.AppendFormat("{0}.Datas.AcceptChanges();{1}", ClientID, c_NewLine);



            jshtml.AppendFormat("setTimeout('{0}.Initialize()',1);", ClientID);

            return jshtml.ToString(); 
        }

        private void CreateEditTemplate(HtmlTextWriter output)
        {
            var shtml = new StringBuilder();

            if (EmptyDataTemplate != null)
                {
                    var cell = new TableCell();
                    EmptyDataTemplate.InstantiateIn(cell);

                    var modal = new Panel();
                    modal.Attributes.Add("class", "ModalDlgMask");
                    modal.ID = ClientID + "ModalDlgMask";

                    var table1 = new Table();
                    table1.Attributes.Add("class", "tfEditTemplate");
                    table1.ID = ClientID + "EditTemplate";
                    var row1 = new TableRow();
                    row1.Cells.Add(cell);
                    table1.Rows.Add(row1);
                    //modal.Controls.Add(table1);
                    modal.RenderControl(output);
                    table1.RenderControl(output);
                }
                else
                {

                    shtml.AppendFormat("<table id={0}EditTemplate class='tfEditTemplate'>{1}", ClientID, c_NewLine);
                    shtml.AppendFormat("<tr class='tfEditTemplateTitle'><td id='{0}TTitle' colspan='2'></br></td></tr>" + c_NewLine,ClientID);
                    c_MyTable = ParseDataSource();
                    string hidCols = "," + hiddenColumns + ",";
                    for (int nX = 0; nX < c_MyTable.Columns.Count; nX++)
                    {
                        DataColumn column = c_MyTable.Columns[nX];
                        if (!hidCols.Contains(","+column.ColumnName+","))
                        {
                            shtml.Append(GetTemplateHTML(column));
                        }
                    }

                    shtml.AppendFormat( "<tr><td id='{0}Footer' colspan='2'></td></tr>",ClientID);
                    //shtml.AppendFormat(
                    //    "<tr><td><input id=\"{0}btnOK\" onclick=\"{0}.Rows.ApplyChanges()\" type=\"button\" value=\"OK\" /></td>" + c_NewLine,
                    //    ClientID);
                    //shtml.AppendFormat(
                    //    "<td><input id=\"{0}btnCan\" onclick=\"{0}.Rows.CancelChanges()\" type=\"button\" value=\"Cancel\" /></td></tr>" + c_NewLine,
                    //    ClientID);
                    shtml.Append(c_NewLine + "</table>");
                    output.Write(shtml.ToString());    
            }
        }

        private void CreateInternalGridColumns()
        {
                 var myBoundField = new LVBoundField
                {
                    DataField = "_tfRI",
                    HeaderText = "_tfRI",
                    SortExpression = "_tfRI",
                    Visible = false
                };
                Columns.Insert(0, myBoundField);

                myBoundField = new LVBoundField
                {
                    DataField = "_tfAT",
                    HeaderText = "_tfAT",
                    SortExpression = "_tfAT",
                    Visible = true
                };
                Columns.Insert(0, myBoundField);
        }

        private DataTable CreateInternalDTColumns(DataTable table)
        {
            if (table.Columns["_tfRI"] == null)
            {
                table.TableName = ClientID + "T";
                table.Columns.Add("_tfRI", typeof(int));
                table.Columns["_tfRI"].SetOrdinal(0);
                table.Columns["_tfRI"].AutoIncrement = true;
                table.Columns["_tfRI"].AutoIncrementSeed = 0;
                table.Columns["_tfRI"].AutoIncrementStep = 1;
                table.Columns.Add("_tfAT", typeof(String));
                table.Columns["_tfAT"].DefaultValue = "00";
                table.Columns["_tfAT"].AllowDBNull = true;
                table.Columns["_tfAT"].SetOrdinal(0);
                table.AcceptChanges();
                foreach (DataRow e in table.Rows)
                {
                    e["_tfAT"] = "00";
                }
            }

            if (Columns.Count == 0)
            {
                foreach (DataColumn col in table.Columns)
                {
                    var myBoundField = new LVBoundField
                    {
                        DataField = col.ColumnName,
                        HeaderText = col.ColumnName,
                        SortExpression = col.ColumnName
                    };
                    if (col.ColumnName == "_tfRI") myBoundField.Visible = false;
                    Columns.Add(myBoundField);
                }
            }
            else
            {
                var myBoundField = new LVBoundField
                {
                    DataField = "_tfRI",
                    HeaderText = "_tfRI",
                    SortExpression = "_tfRI",
                    Visible = false
                };
                Columns.Insert(0, myBoundField);

                myBoundField = new LVBoundField
                {
                    DataField = "_tfAT",
                    HeaderText = "_tfAT",
                    SortExpression = "_tfAT",
                    Visible = true
                };
                Columns.Insert(0, myBoundField);
            }

            return table;
        }

        private DataTable ParseDataSource()
        {
                    if(c_MyTable!=null){return c_MyTable;}
                    tfDataSource = GetMyDataSource(false);
                    if (tfDataSource != null)
                    {
                        // DataTable table = null;

                        if (tfDataSource is DataSet)
                        {
                            tfDataTable = !string.IsNullOrEmpty(DataMember)
                                        ? ((DataSet)tfDataSource).Tables[DataMember]
                                        : ((DataSet)tfDataSource).Tables[0];
                        }
                        else if (tfDataSource is DataTable)
                        {
                            tfDataTable = (DataTable)tfDataSource;
                        }
                        else if (tfDataSource is DataView)
                        {
                            if (((DataView)tfDataSource).Count > 0)
                            {
                                tfDataTable = ((DataView)tfDataSource).Table;
                            }
                        }
                        else if (tfDataSource is System.Linq.Enumerable)
                        {
                            tfDataTable = DataConversion.ToADOTable((IEnumerable)tfDataSource);
                        }
                        else if (tfDataSource is IEnumerable)
                        {
                            tfDataTable = DataConversion.ToADOTable((IEnumerable)tfDataSource);
                        }
                        else if (tfDataSource is ICollection)
                        {
                            //TODO:  Handle an ICollection
                        }
                        else if (tfDataSource is IList)
                        {
                            //TODO:  Handle an IList
                        }
                        else if (tfDataSource is EnumerableRowCollection<DataRow>)
                        {
                            tfDataTable = ((EnumerableRowCollection<DataRow>)tfDataSource).CopyToDataTable();
                        }
                        else
                            tfDataTable = tfDataSource is DataView
                                        ? ((DataView)tfDataSource).Table
                                        : DataConversion.ConvertToDataTable((Object[])tfDataSource);

                        if (tfDataTable != null)
                        {
                            return CreateInternalDTColumns(tfDataTable);
                        }
                    }
                    else
                    {
                        CreateInternalGridColumns();
                    }
            return null;
            }

        #region (ServerRender) Render Grid on Server and pass HTML
        /// <summary>
        /// Renders the entire grid.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <returns></returns>
        private string ServerRender(DataTable table)
        {
            var shtml = new StringBuilder();

            //if(!FreezeHeader)
            //{
                //  style='width: {1}px;height: {2}px; overflow: auto;'
            shtml.AppendFormat("<div id='{0}Container' class='lvCon' style='width: {1};height: {2};'>{3}", ClientID, GridWidth, GridHeight,c_NewLine);
            //}
            shtml.Append(RenderTopPanel());
            shtml.AppendFormat("<div id=\"{0}RDiv\">", ClientID); // Outside Div for rows
            if(table !=null) {shtml.Append(RenderTableData(table));}
            shtml.AppendFormat("</div><div id={0}DDiv></div>{1}",ClientID, c_NewLine);
           // if (!FreezeHeader)
           // {
                shtml.Append("</div>"); // End Container
           // }
            shtml.Append(RenderFooterPanel());
            shtml.AppendFormat(@"<div id={0}BMk></div>{1}<div id='{0}uimg' style='LEFT: 0px; VISIBILITY: hidden; POSITION: absolute; TOP: 0px'>EDev</div>{1}",ClientID,c_NewLine);
            return shtml.ToString();
        }

        /// <summary>
        /// Renders the top panel.
        /// </summary>
        /// <returns></returns>
        private string RenderTopPanel()
        {
            var shtml = new StringBuilder();

            shtml.AppendFormat(@"<div id={0}Hdr>{1}{2}</div>{3}", ClientID, AllowGroupBy ? RenderDragByPane():"", AllowSearch ? RenderSearchPane():"",c_NewLine);

            return shtml.ToString();
        }

        /// <summary>
        /// Renders the drag by pane.
        /// </summary>
        /// <returns></returns>
        private string RenderDragByPane()
        {
            var shtml = new StringBuilder();
            shtml.AppendFormat(
                @"<div id={0}GroupByDrager>{1}<table class='tfDragPanel'>{1}<tbody>{1}<tr>{1}<td onmouseup={0}.Events.Drag.HeaderToGroupBy();>&nbsp;Drag Header here to Group...</td>{1}</tr>{1}</tbody>{1}</table>{1}</div>",
                ClientID,c_NewLine);
            return shtml.ToString();
        }

        /// <summary>
        /// Renders the search pane.
        /// </summary>
        /// <returns></returns>
        private string RenderSearchPane()
        {
            var shtml = new StringBuilder();

            shtml.AppendFormat(
                @"<DIV class='tfSearch' width='100%'>
                    <SELECT class=Selectbox onchange={0}.Tables.Tables[0].Navigator.SearchColumn=this.options[this.options.selectedIndex].value>
                        <OPTION value=-1 selected>All fields</OPTION></SELECT>
                    <INPUT class=spTxtboxs id={0}EDNavTB onchange={0}.Tables.Tables[0].Navigator.Search(this.value)>
                    <DIV class='tfSearch_img' onclick={1}{0}.Tables.Tables[0].Navigator.Search(document.getElementById('{0}EDNavTB').value, true){1}></DIV>
                  </DIV>",
                ClientID, "\"");

            return shtml.ToString();
        }

        /// <summary>
        /// Renders the header table.
        /// </summary>
        /// <returns></returns>
        private string RenderHeaderTable()
        {
            var shtml = new StringBuilder();
            shtml.AppendFormat("<thead>{0}<tr>{0}<th>&nbsp;</th>{0}", c_NewLine);
            var i = 0;

            for (int nXc = 1; nXc < Columns.Count; nXc++) // was table.columns
            {
                DataControlField column = Columns[nXc];
                if (column.Visible)
                {
                    string strSort = "";
                    string strGrp = "";
                    if (AllowSorting) {strSort = String.Format("onclick={0}.Tables.Tables[0].Navigator.Sort({1});", ClientID, 1);}
                    if (AllowGroupBy) {strGrp = String.Format("onmousedown={1}{0}.Events.dragStart(event, '{0}uimg','<div class=HDrag>{2}</div>',{0}.Tables.Tables[0].lvObj.Columns.Columns[{3}]);{1}", ClientID, "\"", column.HeaderText, i);}

                    shtml.AppendFormat(
                        @"<th {0} {1}>{2}<div class=lvSort></div></th>{3}",
                        strGrp, strSort, column.HeaderText,c_NewLine);
                }
            }
            shtml.AppendFormat("</tr>{0}</thead>{0}",c_NewLine);
            return shtml.ToString();
        }

        /// <summary>
        /// Renders the rows.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <returns></returns>
        private string RenderRows(DataTable table)
        {
            var shtml = new StringBuilder();
            int nX = 0;
            var style = "class='tfRow'";

            foreach (DataRow row in table.Rows)
            {
                //var eventArgs = new OnRowCreatedEventArgs(row);
                //InvokeRowCreated(eventArgs);
                
                shtml.AppendFormat("<tr id={0}R{1} {2} onclick=eClk(this); ondblclick=dClk(this); object='{0}.Rows.Rows[{1}]'>", ClientID, nX,style);
                shtml.AppendFormat("<td class='{3}' id=RS{0}{1} colSpan=0>{2}</td>", ClientID, nX, row[0], AllowMultiSelect ? "mRSelU" : "sRSelU"); //_tfAT field

                for (int nXc = 1; nXc < Columns.Count; nXc++) // was table.Columns
                {
                    DataControlField column = Columns[nXc];
                    if (column.Visible)
                    {
                        shtml.AppendFormat("<td id={0}R{1}C{2}>{3}</td>", ClientID, nX, nXc, row[(((LVBoundField)column).DataField)]);
                    }

                }
                shtml.AppendFormat("</tr>{0}",c_NewLine);

                style = style.Contains("edRow") ? "class='tfARow'" : "class='tfRow'";

                nX++;
            }

            return shtml.ToString();
        }


        /// <summary>
        /// Gets the column ID.
        /// </summary>
        /// <param name="columnName">Name of the column.</param>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/26/2008 - 9:11 AM
        /// Modified By: 
        /// </remarks>
        public int GetColumnID(string columnName)
        {
            foreach (DataControlField col in Columns)
            {
                if (col.HeaderText == columnName)
                {
                    int columnID = Columns.IndexOf(col);
                    return columnID;
                }
            }
            return -1;
        }
        /// <summary>
        /// Renders the table data.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <returns></returns>
        private string RenderTableData(DataTable table)
        {
            var shtml = new StringBuilder();

            shtml.AppendFormat(
                @" <table class=lvMainD id={0}Main onmouseover={0}.Activate(); onmouseout={0}.DeActivate(); width='{3}';>
                    <tbody>
                    <tr>
                    <td id={0}GroupBy>
                    <table class='{4} tfRow tfHeader' style='Width:{3};' id='{0}edTable0'>{1}<tbody>{2}</tbody>",
                        ClientID, table!=null ? RenderHeaderTable():"", 
                        table!=null ? RenderRows(table):"",GridWidth,FreezeHeader ? "edTable" : "edTable");

            shtml.AppendFormat("</table>{0}</td>{0}</tr>{0}</tbody>{0}</table>{0}", c_NewLine);

//            shtml.Append("</td></tr></tbody></table>");
            

            return shtml.ToString();
        }

        /// <summary>
        /// Renders the footer panel.
        /// </summary>
        /// <returns></returns>
        private string RenderFooterPanel()
        {
            var sb = new StringBuilder();
            var shtml = new StringBuilder();
            sb.Append("<DIV id={0}Ftr><TABLE class=tfFooter width='{1}' id={0}Tbl0PagePanel><TBODY><TR><TD width=10>&nbsp;</TD>");

            if(AllowEdit) {
                sb.Append("<TD><INPUT id={0}_upd onclick={0}.Tables.Tables[0].Navigator.lvObj.GeneralFunctions.SendData({0}.Tables.Tables[0].Navigator.lvObj) type=button align=absMiddle value=Update>&nbsp; </TD>");
                }
            if(AllowAdd) {
                sb.Append("<TD><INPUT id={0}_add onclick={0}.Tables.Tables[0].AddNewRow() type=button align=absMiddle value='New'></TD>");
                }
            if(AllowDelete) {
                sb.Append("<TD><INPUT id={0}_del onclick={0}.Rows.DeleteSelectedRows() type=button align=absMiddle value='Remove'></TD>");
                }
            
            if(AllowMoveRows) {
                sb.Append("<TD><INPUT id={0}_upd onclick={0}.Tables.Tables[0].MoveRowUp() type=button align=absMiddle value=Up>&nbsp; </TD><TD><INPUT id={0}_upd onclick={0}.Tables.Tables[0].MoveRowDown() type=button align=absMiddle value=Dn>&nbsp; </TD>");
                }


            sb.Append(@"<TD id={0}SBar width=10>&nbsp;</TD>
                    <TD align=right width='90%'>Items:&nbsp; <SELECT class=Selectbox onchange={0}.Tables.Tables[0].Navigator.ChangeRowLimit(this.options[this.options.selectedIndex].value)> <OPTION value=10000 selected>All</OPTION> <OPTION value=5>5</OPTION> <OPTION value=10>10</OPTION> <OPTION value=15>15</OPTION> <OPTION value=20>20</OPTION> <OPTION value=30>30</OPTION> <OPTION value=50>50</OPTION> <OPTION value=100>100</OPTION></SELECT>&nbsp;&nbsp;&nbsp;<A href='javascript:{0}.Tables.Tables[0].Navigator.ChangePageIndex(1)'><IMG height=15 src='/Triad.Controls/images/first.jpg' width=15 border=0 valign='bottom'></A>&nbsp;</TD>
                    <TD><A href='javascript:{0}.Tables.Tables[0].Navigator.ChangePageIndex(0)'><IMG height=15 src='/Triad.Controls/images/previous.jpg' width=15 border=0></A>&nbsp;</TD>
                    <TD>&nbsp;&nbsp;<INPUT class=spTxtboxs id={0}sss style='WIDTH: 20px' onchange={0}.Tables.Tables[0].Navigator.ChangePageIndex(this.value) size=2 value=1> / 1&nbsp;&nbsp;</TD>
                    <TD><A href='javascript:{0}.Tables.Tables[0].Navigator.ChangePageIndex(2)'><IMG height=15 src='/Triad.Controls/images/next.jpg' width=15 border=0></A>&nbsp;</TD>
                    <TD><A href='javascript:{0}.Tables.Tables[0].Navigator.ChangePageIndex(1)'><IMG height=15 src='/Triad.Controls/images/last.jpg' width=15 border=0></A>&nbsp;</TD>
                    </TR>
                    </TBODY>
                    </TABLE>
                  </DIV>
            ");

            shtml.AppendFormat(sb.ToString(), ClientID, GridWidth);

            return shtml.ToString();
        }

        #endregion
    }
}